#pragma once

namespace boolstring
{
	enum BI_NODE_TYPE
	{
		BI_NODE_TYPE_AND = 1,
		BI_NODE_TYPE_OR,
	};

	class Node
	{
	public:
		virtual bool Exec() = 0;
	};

	class LogicNode : public Node
	{
	public:
		LogicNode(int logicID) : logicID(logicID) {}

		virtual bool Exec()
		{
			return (logicID < 2000);
		}

	private:
		int logicID;
	};

	class ReverseNode : public Node
	{
	public:
		ReverseNode() : child(nullptr) {}

		virtual bool Exec()
		{
			if (child != nullptr)
			{
				return !child->Exec();
			}
			else
			{
				return false;
			}
		}

	private:
		Node* child;
	};

	class BiNode : public Node
	{
	public:
		BiNode(BI_NODE_TYPE type) : type(type), left(nullptr), right(nullptr) {}

		void AddLeft(Node* n)
		{
			left = n;
		}

		void AddRight(Node* n)
		{
			right = n;
		}

		virtual bool Exec()
		{
			if (left != nullptr || right != nullptr)
			{
				if (type == BI_NODE_TYPE_AND)
				{
					return left->Exec() && right->Exec();
				}
				else if (type == BI_NODE_TYPE_OR)
				{
					return left->Exec() || right->Exec();
				}
				else
				{
					return false;
				}
			}
			else
			{
				return false;
			}
		}

	private:
		BI_NODE_TYPE type;
		Node* left;
		Node* right;
	};

}